#ifndef PW_PBL_INTERFACE_HPP
#define PW_PBL_INTERFACE_HPP

#include "Box.hpp"
#include "Macro.hpp"
#include "Concepts/Core.hpp"
#include "RustMimic.hpp"
#include "ValueType.hpp"
#include "Math.hpp"
#include <tuple>

namespace pw_pbl
{
	namespace Interface
	{
		/// 当对象没有直接实现接口时，可通过特化定义代理虚表来代理实现接口
		/// @note 特化定义的类型必须是DSC::TRawVTable才有效
		template <typename DSC, typename _tObj>
		extern constexpr std::tuple<> ProxyVTable = {};
	} // namespace Interface

	/// 检查类型是否满足指定接口的concept
	/// @tparam T 要检查的类型
	/// @tparam ...INTERFACE 接口类型
	template <typename T, typename... INTERFACE>
	concept ccHasInterface = ((INTERFACE::template CanFrom<T> || std::same_as<decltype(Interface::ProxyVTable<INTERFACE, T>), const typename INTERFACE::TRawVTable>) && ...);

	/// 任意对象接口
	/// @note 所有接口隐含IAny接口
	/// @note 一般只用于内部标记，除析构函数外不提供额外操作方法，显式使用时一般用于同步锁之类只依赖析构函数的对象
	class IAny;
} // namespace pw_pbl

namespace pw_pbl::Interface
{
	template <typename DSC>
	class TRef;

	namespace _imp
	{
		template <typename DSC, typename T>
		struct TWrapped;

		template <typename DSC = IAny>
		struct SVTable;

		template <>
		struct SVTable<IAny>
		{
			void (*destruct)(void *) = [](void *) {};
		};

		template <typename DSC>
		struct SVTable : public SVTable<IAny>, public DSC::TRawVTable
		{};

		template <typename DSC>
		struct SVTableM : public SVTable<DSC>
		{
			void (*move_construct_to)(void *self, void *tgt);
		};

		template <typename... DSC>
		struct TVObject;

		template <>
		struct TVObject<>
		{
			static constexpr auto EStatusBitsCnt = 1;
			static_assert(Math::Log2Floor(alignof(SVTable<>)) >= EStatusBitsCnt); // 虚表指针至少2字节对齐

			uintptr_t mbOffseted : EStatusBitsCnt;							  //< 指示跟随的对象是否因对齐超限而进行地址偏移（即非直接跟随对象数据，而是跟随指向对象数据的指针
			uintptr_t mipVTable : Math::BitCntOf<uintptr_t> - EStatusBitsCnt; //< 虚表指针，低位由于对齐原因复用于上面的用途

			inline const SVTable<> *pVTable() const noexcept { return (const SVTable<> *)(mipVTable << EStatusBitsCnt); }
			inline void *pObj() noexcept { return mbOffseted ? *(void **)&this[1] : (void *)&this[1]; }
			inline const void *pObj() const noexcept { return mbOffseted ? *(void *const *)&this[1] : (const void *)&this[1]; }
			void copy_header_from(const TVObject<> &oth)
			{
				*this = oth;
				if (oth.mbOffseted)
					*(char **)&this[1] = (char *)this + (*(char **)&(&oth)[1] - (char *)&oth);
			}

			inline void destruct() noexcept { pVTable()->destruct(pObj()); }
		};

		template <typename DSC>
		struct TVObject<DSC> : public TVObject<>
		{
			inline const SVTable<DSC> *pVTable() noexcept { return (const SVTable<DSC> *)TVObject<>::pVTable(); }

			inline constexpr TVObject(bool offseted, const SVTable<DSC> &vtable) noexcept : TVObject<>{.mbOffseted = offseted, .mipVTable = (uintptr_t)(&vtable) >> EStatusBitsCnt}
			{
				static_assert(sizeof(TVObject) == sizeof(TVObject<>) && sizeof(TVObject) == sizeof(const SVTable<DSC> *) && alignof(TVObject) == alignof(TVObject<>));
			}
		};

		template <typename DSC, typename T>
		struct TWrapped : public TVObject<DSC>
		{
			T obj;
			static constexpr auto EBaseAlign = alignof(const SVTable<> *);
			static constexpr auto EBaseAlignMask = EBaseAlign - 1;
			constexpr TWrapped(const SVTable<DSC> &vtable, T &&_obj) noexcept : TVObject<DSC>{false, vtable}, obj{std::forward<T>(_obj)}
			{
				static_assert(alignof(TWrapped) == alignof(TVObject<DSC>));
				static_assert((sizeof(T) + sizeof(TVObject<DSC>) + EBaseAlignMask & ~EBaseAlignMask) == sizeof(TWrapped));
			}
			TWrapped(auto &) = delete;
			constexpr TWrapped(TWrapped &&) = default;
			TWrapped(const TWrapped &) = delete;
		};

		template <typename DSC, typename T> requires(alignof(T) > alignof(TVObject<DSC>))
		struct TWrapped<DSC, T> : public TVObject<DSC>
		{
			T *ptr;
			T obj;
			constexpr TWrapped(const SVTable<DSC> &vtable, T &&_obj) noexcept : TVObject<DSC>{true, vtable}, ptr{&obj}, obj{std::forward<T>(_obj)} {}
			TWrapped(auto &) = delete;
			constexpr TWrapped(TWrapped &&) = default;
			TWrapped(const TWrapped &) = delete;
		};

		template <typename DSC>
		struct TVTableRef
		{
			const typename DSC::TRawVTable *ptr;

			constexpr TVTableRef(const typename DSC::TRawVTable &p) noexcept : ptr{&p} {}
			template <typename ODSC>
			constexpr TVTableRef(TVTableRef<ODSC> oth) noexcept : ptr{&oth.get()} {}
			constexpr const typename DSC::TRawVTable &get() const { return *ptr; }
		};

		template <typename DSC> requires(sizeof(typename DSC::TRawVTable) <= sizeof(typename DSC::TRawVTable *))
		struct TVTableRef<DSC>
		{
			typename DSC::TRawVTable vtable;

			constexpr TVTableRef(const typename DSC::TRawVTable &p) noexcept : vtable{p} {}
			template <typename ODSC>
			constexpr TVTableRef(TVTableRef<ODSC> oth) noexcept : vtable{oth.get()} {}
			constexpr const typename DSC::TRawVTable &get() const { return vtable; }
		};

		template <typename T, typename DSC, typename SELF>
		concept ccImp = (!std::is_base_of_v<SELF, std::decay_t<T>>) && (!ccDerivedFrom<T, TRef>) && ccHasInterface<T, DSC>;
	} // namespace _imp

	template <typename DSC, typename _tObj>
	extern constexpr _imp::SVTable<DSC> AutoVTable = {AutoVTable<IAny, _tObj>, {ProxyVTable<DSC, _tObj>}};

	template <typename DSC, typename _tObj> requires(DSC::template CanFrom<_tObj>)
	extern constexpr _imp::SVTable<DSC> AutoVTable<DSC, _tObj> = {AutoVTable<IAny, _tObj>, {DSC::template ClassVTable<_tObj>}};

	template <typename _tObj>
	extern constexpr _imp::SVTable<IAny> AutoVTable<IAny, _tObj> = {.destruct = [](void *ptr) { ((_tObj *)ptr)->~_tObj(); }};

	template <typename _tObj> requires std::is_trivially_destructible_v<_tObj>
	extern constexpr _imp::SVTable<IAny> AutoVTable<IAny, _tObj> = {};

	template <typename DSC, typename _tObj>
	extern constexpr _imp::SVTableM<DSC> AutoVTableM = {AutoVTable<DSC, _tObj>, [](void *self, void *tgt) { new (tgt) _tObj{std::move(*(_tObj *)self)}; }};

	/// 接口的引用类型，语义相当于可空左值引用
	/// @tparam DSC 接口的描述
	template <typename DSC>
	class TRef : public DSC::TRawRef
	{
		static_assert(std::is_empty_v<typename DSC::TRawRef>);
		template <typename>
		friend class TRef;

	protected:
		_imp::TVTableRef<DSC> _mVTable;
		const void *_mpObj;

		explicit inline constexpr TRef(const typename DSC::TRawVTable &vtable, void *pObj) noexcept : _mVTable{vtable}, _mpObj{pObj} {}

	public:
		template <_imp::ccImp<DSC, TRef> T>
		inline constexpr TRef(T &obj) noexcept : _mVTable{AutoVTable<DSC, T>}, _mpObj{&obj} {}

		template <typename T>
		inline constexpr TRef(T &obj, const typename DSC::TRawVTable &vtable) noexcept : _mVTable{vtable}, _mpObj{&obj} {}

		constexpr TRef(const TRef &oth) noexcept = default;
		constexpr TRef(TRef &&oth) noexcept = default;
		constexpr TRef &operator=(const TRef &oth) noexcept = default;
		constexpr TRef &operator=(TRef &&oth) noexcept = default;

		template <typename ODSC> requires std::derived_from<typename ODSC::TRawVTable, typename DSC::TRawVTable>
		constexpr TRef(const TRef<ODSC> &oth) noexcept : _mVTable{oth._mVTable}, _mpObj{oth._mpObj} {}

		inline const typename DSC::TRawVTable &VTable() const noexcept { return _mVTable.get(); }
		inline void *pObj() const noexcept { return const_cast<void *>(_mpObj); }

		explicit inline operator bool() const noexcept { return _mpObj != nullptr; }

		struct Structural;
	};

	/// 接口的万能引用类型，语义相当于可空万能引用，不可复制，通常作为函数参数，代理调用后丢弃
	/// @tparam DSC 接口的描述
	template <typename DSC>
	class TURef : public TRef<DSC>
	{
	public:
		using TRef<DSC>::TRef;

		template <_imp::ccImp<DSC, TURef> T>
		inline constexpr TURef(T &&obj) noexcept : TRef<DSC>{obj} {}

		template <typename T>
		inline constexpr TURef(T &&obj, const typename DSC::TRawVTable &vtable) noexcept : TRef<DSC>{obj, vtable} {}

		TURef(TURef &&) = default;
		TURef(const TURef &) = delete;
		template <typename ODSC>
		TURef(const TRef<ODSC> &) = delete;
	};

	/// 接口的指针类型，语义相当于指针，支持->和*操作
	/// @tparam DSC 接口的描述
	template <typename DSC>
	class TPtr : protected TRef<DSC>
	{
	public:
		explicit inline constexpr TPtr(const typename DSC::TRawVTable &vtable, void *pObj) noexcept : TRef<DSC>{vtable, pObj} {}
		constexpr TPtr(const TRef<DSC> &ref) noexcept : TRef<DSC>{ref} {}
		template <typename ODSC> requires std::derived_from<typename ODSC::TRawVTable, typename DSC::TRawVTable>
		constexpr TPtr(const TPtr<ODSC> &oth) noexcept : TRef<DSC>{oth} {}

	public:
		inline constexpr TRef<DSC> *operator->() noexcept { return this; }
		inline constexpr TRef<DSC> &operator*() noexcept { return *this; }

		inline void *pObj() const noexcept { return const_cast<void *>(this->_mpObj); }
		inline constexpr const typename DSC::TRawVTable &VTable() const noexcept { return this->_mVTable.get(); }
	};
	template <typename DSC>
	TPtr(TRef<DSC>) -> TPtr<DSC>;

	/// 接口的引用类型，语义相当于可空左值引用，用于模板非类型参数中
	/// @tparam DSC 接口的描述
	template <typename DSC>
	struct TRef<DSC>::Structural
	{
		_imp::TVTableRef<DSC> _mVTable;
		const void *_mpObj;

		constexpr Structural(TRef<DSC> ref) noexcept : _mVTable{ref._mVTable}, _mpObj{ref._mpObj} {}
		constexpr operator TRef<DSC>() const noexcept { return TRef<DSC>{_mVTable.get(), const_cast<void *>(_mpObj)}; }
		inline constexpr TRef<DSC> operator*() const noexcept { return TRef<DSC>{_mVTable.get(), const_cast<void *>(_mpObj)}; }
		inline constexpr TPtr<DSC> operator->() const noexcept { return TPtr<DSC>{_mVTable.get(), const_cast<void *>(_mpObj)}; }
	};

	/// 接口的万能转发器，可从左值和右值引用构造
	/// @tparam DSC 接口的描述
	/// @tparam ...LRVALUE 左右值限定选项，为空表示左右值引用均可，为true表示右值，为false表示左值
	template <typename DSC, bool... RVALUE>
	class TForwarder;

	/// 接口的左值转发器，可从左值引用构造
	/// @tparam DSC 接口的描述
	template <typename DSC>
	using TLForwarder = TForwarder<DSC, false>;

	/// 接口的右值转发器，可从右值引用构造
	/// @tparam DSC 接口的描述
	template <typename DSC>
	using TRForwarder = TForwarder<DSC, true>;

	template <typename DSC, typename... ALLOCATOR>
	class TBox;

	template <typename DSC>
	struct TPublicTypes
	{
		/// 接口的装箱类型
		/// @tparam ...APARMS 传给pw_pbl::Box的分配器参数
		template <typename... APARMS>
		using Box = std::conditional_t<sizeof...(APARMS) == 0, DSC, TBox<DSC, APARMS...>>;

		/// 接口的混合装箱类型，自带存储空间且可动态分配内存，当自带的存储空间大小和对齐合适时则使用自带存储空间，否则使用动态分配的存储空间
		/// @tparam LAYOUT 自带存储空间的布局
		/// @tparam ...APARMS 传给pw_pbl::Box的分配器参数
		template <AllocLayout LAYOUT = {}, typename... APARMS>
		using MixBox = TBox<DSC, vtAllocLayout<LAYOUT>, pw_pbl::Box<APARMS...>>;

		/// 接口的引用类型，语义相当于引用，但支持->和*操作
		using Ref = TRef<DSC>;

		/// 接口的万能引用类型，语义相当于万能引用，但支持->和*操作，不可复制，通常作为函数参数，代理调用后丢弃
		using URef = TURef<DSC>;

		/// 接口的万能转发器，可从左值和右值引用构造
		using Forwarder = TForwarder<DSC>;

		/// 接口的左值转发器，可从左值引用构造
		using LForwarder = TLForwarder<DSC>;

		/// 接口的右值转发器，可从右值引用构造
		using RForwarder = TRForwarder<DSC>;
	};

	namespace _box
	{
		template <typename DSC, typename... ALLOCATOR>
		struct TBox
		{
			pw_pbl::Box<ALLOCATOR...> _mWrapped;

			inline _imp::TVObject<DSC> &_VObject() noexcept { return *(_imp::TVObject<DSC> *)_mWrapped.get(); }
			inline void *_pObj() noexcept { return _VObject().pObj(); }
			inline const _imp::SVTable<DSC> &VTable() noexcept { return *_VObject().pVTable(); }
			static inline auto _destruct() noexcept
			{
				return [](void *p) { ((_imp::TVObject<> *)p)->destruct(); };
			}

			constexpr TBox() = default;
			constexpr ~TBox() noexcept { _mWrapped.OnDestruct(_destruct()); }
			TBox(TBox &&) = default;
			template <typename T>
			constexpr TBox(T &&obj) noexcept : _mWrapped(_imp::TWrapped<DSC, T>(AutoVTable<DSC, T>, std::forward<T>(obj))) {}
			template <bool... RVALUE>
			constexpr TBox(TForwarder<DSC, RVALUE...> fwr) noexcept
			{
				auto [size, align, constructor] = fwr.WrappedConstructor();
				_mWrapped.OnConstruct(size, align, constructor);
			}
			template <typename T>
			constexpr void _assign(T &&obj) noexcept { _mWrapped.template remake<_imp::TWrapped<DSC, T>>(_destruct(), AutoVTable<DSC, T>, std::forward<T>(obj)); }
			template <bool... RVALUE>
			constexpr void _assign(TForwarder<DSC, RVALUE...> fwr) noexcept
			{
				auto [size, align, constructor] = fwr.WrappedConstructor();
				_mWrapped.remake(_destruct(), size, align, constructor);
			}

			explicit inline operator bool() const noexcept { return bool(_mWrapped); }
		};

		template <typename DSC, typename... APARMS>
		struct TBox<DSC, pw_pbl::Box<APARMS...>>
		{
			_imp::TVTableRef<DSC> _mVTable;
			pw_pbl::Box<APARMS...> _mWrapped;

			inline void *_pObj() noexcept { return _mWrapped.get(); }
			inline const _imp::SVTable<DSC> &VTable() noexcept { return _mVTable.get(); }

			constexpr TBox() = default;
			constexpr ~TBox() noexcept { _mWrapped.OnDestruct(_mVTable.get().destruct); }
			TBox(TBox &&) = default;
			template <typename T>
			constexpr TBox(T &&obj) noexcept : _mVTable{AutoVTable<DSC, T>}, _mWrapped(std::forward<T>(obj)) {}
			template <bool... RVALUE>
			constexpr TBox(TForwarder<DSC, RVALUE...> fwr) noexcept : _mVTable{fwr.VTable()}, _mWrapped(fwr.Size(), fwr.Align(), fwr.Constructor()) {}
			template <typename T>
			constexpr void _assign(T &&obj) noexcept { _mWrapped.template remake<T>(std::exchange(_mVTable, AutoVTable<DSC, T>).get().destruct, std::forward<T>(obj)); }
			template <bool... RVALUE>
			constexpr void _assign(TForwarder<DSC, RVALUE...> fwr) noexcept { _mWrapped.remake(std::exchange(_mVTable, fwr.VTable()).get().destruct, fwr.Size(), fwr.Align(), fwr.Constructor()); }

			explicit inline operator bool() const noexcept { return bool(_mWrapped); }
		};

		template <typename DSC, AllocLayout LAYOUT>
		struct TBox<DSC, vtAllocLayout<LAYOUT>>
		{
			using PVTable = const _imp::SVTableM<DSC> *;

			pw_pbl::Box<vtAllocLayout<LAYOUT>, PVTable> _mWrapped;

			inline void *_pObj() noexcept { return _mWrapped.get(); }
			inline const _imp::SVTableM<DSC> &VTable() noexcept { return *_mWrapped.Tailer(); }

			constexpr TBox() noexcept : _mWrapped(PVTable(nullptr)) {}
			constexpr ~TBox() noexcept { VTable().destruct(_pObj()); }
			constexpr TBox(TBox &&oth) : _mWrapped(std::move(oth._mWrapped.Tailer())) { oth.VTable().move_construct_to(oth._pObj(), this->_pObj()); }
			template <typename T>
			constexpr TBox(T &&obj) noexcept : _mWrapped(&AutoVTableM<DSC, T>, std::forward<T>(obj)) {}
			template <bool... RVALUE>
			constexpr TBox(TForwarder<DSC, RVALUE...>) = delete;
			template <typename T>
			constexpr void _assign(T &&obj) noexcept { std::destroy_at(this), std::construct_at(this, std::forward<T>(obj)); }
			template <bool... RVALUE>
			constexpr void _assign(TForwarder<DSC, RVALUE...>) = delete;

			explicit inline operator bool() const noexcept { return _mWrapped.Tailer(); }
		};

		/// 混合装箱的特化，自带存储空间且可动态分配内存，当自带的存储空间大小和对齐合适时则使用自带存储空间，否则使用动态分配的存储空间
		template <typename DSC, AllocLayout LAYOUT, typename... APARAMS>
		struct TBox<DSC, vtAllocLayout<LAYOUT>, pw_pbl::Box<APARAMS...>>
		{
			using DynamicBox = pw_pbl::Box<APARAMS...>;
			static constexpr auto EStatusBitsCnt = 1;
			struct MixPVtable
			{
				uintptr_t bAllocated : EStatusBitsCnt;
				uintptr_t ptr : Math::BitCntOf<uintptr_t> - EStatusBitsCnt;

				inline const _imp::SVTableM<DSC> &VTable() const noexcept { return *(const _imp::SVTableM<DSC> *)(ptr << EStatusBitsCnt); }
			};
			using StaticBox = pw_pbl::Box<vtAllocLayout<{.size = std::max(LAYOUT.size, sizeof(DynamicBox)), .align = std::max(LAYOUT.align, alignof(DynamicBox))}>, MixPVtable>;

			StaticBox _mWrapped;

			inline DynamicBox *_pBox() { return reinterpret_cast<DynamicBox *>(_pStatic()); } // 静态箱里存储一个动态箱而不是直接对象
			inline void *_pStatic() { return _mWrapped.get(); }
			constexpr MixPVtable &_tailer() { return _mWrapped.Tailer(); }
			constexpr const MixPVtable &_tailer() const { return _mWrapped.Tailer(); }
			inline void *_pObj() { return _tailer().bAllocated ? _pBox()->get() : _pStatic(); }
			inline const _imp::SVTableM<DSC> &VTable() const noexcept { return _tailer().VTable(); }

			template <typename T>
			static constexpr bool ENeedAlloc = !StaticBox::template EAllocable<T>; // 仅对齐超过仍有可能不分配，但机率较少且代价较大（增加一个位且要移动逻辑复杂）所以不处理

			template <typename T>
			static MixPVtable gen_tailer() { return {.bAllocated = ENeedAlloc<T>, .ptr = uintptr_t(&AutoVTableM<DSC, T>) >> EStatusBitsCnt}; }

			constexpr TBox() noexcept : _mWrapped(MixPVtable{}) {}
			constexpr ~TBox() noexcept
			{
				if (auto &tailer = _tailer(); tailer.bAllocated)
					_pBox()->OnDestruct(tailer.VTable().destruct), std::destroy_at(_pBox());
				else if (tailer.ptr)
					tailer.VTable().destruct(_pStatic());
			}
			constexpr TBox(TBox &&oth) : _mWrapped(std::move(oth._tailer()))
			{
				if (auto &tailer = _tailer(); tailer.bAllocated)
					std::construct_at(_pBox(), std::move(*oth._pBox()));
				else if (tailer.ptr)
					tailer.VTable().move_construct_to(oth._pStatic(), this->_pStatic()), tailer.VTable().destruct(oth._pStatic()), oth._tailer() = {}; // 保持与动态Box移动行为一致
			}
			template <typename T>
			constexpr TBox(T &&obj) noexcept : _mWrapped(gen_tailer<T>())
			{
				if constexpr (ENeedAlloc<T>)
					std::construct_at(_pBox(), std::forward<T>(obj));
				else
					new (_pStatic()) T(std::forward<T>(obj));
			}
			template <bool... RVALUE>
			constexpr TBox(TForwarder<DSC, RVALUE...>) = delete;

			template <typename T>
			constexpr void _assign(T &&obj) noexcept
			{
				if constexpr (ENeedAlloc<T>)
				{
					if (auto &tailer = _tailer(); tailer.bAllocated)
						_pBox()->template remake<T>(std::exchange(_tailer(), gen_tailer<T>()).pVTable()->destruct, std::forward<T>(obj));
					else
					{
						if (tailer.ptr)
							tailer.VTable().destruct(_pStatic()), std::destroy_at(&tailer);
						std::construct_at(this, std::forward<T>(obj));
					}
				}
				else
					std::destroy_at(this), std::construct_at(this, std::forward<T>(obj));
			}
			template <bool... RVALUE>
			constexpr void _assign(TForwarder<DSC, RVALUE...>) = delete;

			explicit inline operator bool() const noexcept { return _tailer().bAllocated ? bool(*(const DynamicBox *)_mWrapped.get()) : _tailer().ptr; }
		};

		template <typename DSC, typename... APARM0, typename... ALLOCATOR> requires(sizeof...(ALLOCATOR) != 0)
		class TBox<DSC, pw_pbl::Box<APARM0...>, ALLOCATOR...>
		{
			static_assert(sizeof...(ALLOCATOR) == 0);
		};

		template <typename DSC, AllocLayout LAYOUT, typename... APARAMS>
		class TBox<DSC, pw_pbl::Box<vtAllocLayout<LAYOUT>, APARAMS...>>
		{
			static_assert(LAYOUT.size != vtAllocLayout<LAYOUT>::value);
		};
	} // namespace _box

	/// 接口的装箱类型，默认等同于类型化的pw_pbl::Box，通常为一个指针大小；当分配器自身就是pw_pbl::Box时，通常至少两个指针大小；当使用静态存储时，通常为指定容量加一个指针大小
	/// @tparam DSC 接口的描述
	/// @tparam ...APARAMS 传给pw_pbl::Box的分配器参数，根据不同参数使用不同的内存分配方法:
	///   - TBox<DSC, vtAllocLayout<LAYOUT>, pw_pbl::Box<...>> 混合装箱形式，自带存储空间且可动态分配内存，当自带的存储空间布局合适时则使用自带存储空间，否则使用动态分配的存储空间
	///   - TBox<DSC, vtAllocLayout<LAYOUT>> 静态装箱形式，仅使用自带存储空间分配，分配失败则直接编译期报错
	///   - TBox<DSC, pw_pbl::Box<...>> 双指针形式，一个指针指向虚表，一个指针指向动态分配的对象
	///   - TBox<DSC, APARAMS...> 单指针形式，等同于类型化的pw_pbl::Box<APARAMS...>，虚表指针包含在动态分配的内存当中
	template <typename DSC, typename... APARAMS>
	class TBox : protected _box::TBox<DSC, APARAMS...>, public TPublicTypes<DSC>
	{
		using _tBase = _box::TBox<DSC, APARAMS...>;

	public:
		/// Box默认不能为空，必须显式构造为空
		explicit constexpr TBox(None_t) : _tBase{} {}
		template <_imp::ccImp<DSC, TBox> T>
		constexpr TBox(T &&obj) noexcept : _tBase{std::forward<T>(obj)} {}
		TBox(TBox &&oth) = default;
		TBox(auto &obj) = delete;

		template <typename T>
		TBox(TRef<T>) = delete;

		template <typename T>
		TBox(TLForwarder<T>) = delete;

		template <bool... RVALUE>
		constexpr TBox(TForwarder<DSC, RVALUE...> fwr) noexcept : _tBase{std::move(fwr)} {}

		template <_imp::ccImp<DSC, TBox> T>
		constexpr TBox &operator=(T &&obj) noexcept { return this->_assign(std::forward<T>(obj)), *this; }
		constexpr TBox &operator=(TBox &&oth) noexcept { return this->~TBox(), new (this) TBox(std::move(oth)), *this; }
		TBox &operator=(auto &) = delete;

		template <typename T>
		void operator=(TRef<T>) = delete;

		template <typename T>
		void operator=(TLForwarder<T>) = delete;

		template <bool... RVALUE>
		constexpr TBox &operator=(TForwarder<DSC, RVALUE...> fwr) noexcept { return this->_assign(std::move(fwr)), *this; }

		using _tBase::operator bool;
		constexpr bool operator==(None_t) const { return !bool(*this); }
		inline constexpr TRef<DSC> operator*() noexcept { return *TPtr<DSC>{this->VTable(), this->_pObj()}; }
		inline constexpr TPtr<DSC> operator->() noexcept { return TPtr<DSC>{this->VTable(), this->_pObj()}; }

	public:
		using SHandle = typename decltype(_tBase::_mWrapped)::SHandle;
		inline constexpr SHandle handle() const noexcept { return this->_mWrapped.handle(); }
	};
} // namespace pw_pbl::Interface

namespace pw_pbl
{
	template <typename... DSC>
	class IJoin;

	namespace Interface
	{
		namespace _imp
		{
			template <typename JOIN>
			struct IsIJoin : public std::false_type
			{};

			template <typename... DSC>
			struct IsIJoin<IJoin<DSC...>> : public std::true_type
			{};
		} // namespace _imp

		template <typename JOIN>
		concept ccIsIJoin = _imp::IsIJoin<JOIN>::value;

		template <typename JOIN>
		concept ccNotIJoin = (!_imp::IsIJoin<JOIN>::value);

		template <ccIsIJoin... JOIN>
		struct Concat;

		template <typename... DSC>
		struct Concat<IJoin<DSC...>>
		{
			using type = IJoin<DSC...>;
		};
		template <typename... DSC, typename... DSC2>
		struct Concat<IJoin<DSC...>, IJoin<DSC2...>>
		{
			using type = IJoin<DSC..., DSC2...>;
		};
		template <ccIsIJoin FIRST, ccIsIJoin... JOIN>
		struct Concat<FIRST, JOIN...>
		{
			using type = IJoin<FIRST, typename Concat<JOIN...>::type>;
		};

		namespace _imp
		{
			template <typename F>
			struct TStaticVFunc;

			template <typename R, typename... P>
			struct TStaticVFunc<R(P...)>
			{
				using type = R(void *, P...);
				using result_type = R;
			};
		} // namespace _imp

		template <typename F>
		using TStaticVFunc = typename _imp::TStaticVFunc<F>::type;

		template <typename F>
		using TResultType = typename _imp::TStaticVFunc<F>::result_type;

	} // namespace Interface

	namespace _interface
	{
		template <auto MFP, typename PROTYPE>
		struct _classOfMfp;

		template <typename O, typename R, typename... P, R (O::*MFP)(P...)>
		struct _classOfMfp<MFP, R(P...)>
		{
			using type = O;
		};

		template <typename O, typename R, typename... P, R (O::*MFP)(P...) const>
		struct _classOfMfp<MFP, R(P...)>
		{
			using type = const O;
		};

		template <auto MFP, typename PROTYPE>
		using classOfMfp = typename _classOfMfp<MFP, PROTYPE>::type;
	} // namespace _interface
} // namespace pw_pbl

#define _pw_pbl_INTERFACE_ITEM0(i0, ...) i0
#define _pw_pbl_INTERFACE_ITEM1(i0, i1, ...) i1
#define _pw_pbl_INTERFACE_NAME(item) _pw_pbl_INTERFACE_ITEM0 item
#define _pw_pbl_INTERFACE_TYPE(item) _pw_pbl_INTERFACE_ITEM1 item
#define _pw_pbl_INTERFACE_ITEM0_2(i0, i1, i2, ...) i2
#define _pw_pbl_INTERFACE_ITEM0OR2(i0, i1, ...) _pw_pbl_INTERFACE_ITEM0##__VA_OPT__(_2)(i0, i1, __VA_ARGS__)
#define _pw_pbl_INTERFACE_ID_NAME(item) _pw_pbl_INTERFACE_ITEM0OR2 item
#define _pw_pbl_INTERFACE_RESULT(item) _pw_pbl_INTERFACE_CONCAT _pw_pbl_LPAREN _r_, _pw_pbl_INTERFACE_ID_NAME(item) _pw_pbl_RPAREN
#define _pw_pbl_INTERFACE_PARMS(item) _pw_pbl_INTERFACE_CONCAT _pw_pbl_LPAREN _p_, _pw_pbl_INTERFACE_ID_NAME(item) _pw_pbl_RPAREN
#define _pw_pbl_INTERFACE_VTABLE_DEFI(item) ::pw_pbl::Interface::TStaticVFunc<_pw_pbl_INTERFACE_TYPE(item)> *_pw_pbl_INTERFACE_ID_NAME(item)
#define _pw_pbl_INTERFACE_VTABLE_INIT(item) []<typename... P>(void *This, P... p) { return static_cast<::pw_pbl::Interface::TResultType<_pw_pbl_INTERFACE_TYPE(item)>>(((_tObj *)This)->_pw_pbl_INTERFACE_NAME(item)(std::forward<P>(p)...)); }
#define _pw_pbl_INTERFACE_VMETHOD(item)                                                                                        \
	_pw_pbl_INTERFACE_RESULT(item) _pw_pbl_INTERFACE_NAME(item)(this const auto &self, _pw_pbl_INTERFACE_PARMS(item)... _p)    \
	{                                                                                                                          \
		return self.VTable()._pw_pbl_INTERFACE_ID_NAME(item)(self.pObj(), std::forward<_pw_pbl_INTERFACE_PARMS(item)>(_p)...); \
	}
#define _pw_pbl_INTERFACE_REUQIRES(item) typename ::pw_pbl::_interface::classOfMfp<&_tObj::_pw_pbl_INTERFACE_NAME(item), _pw_pbl_INTERFACE_TYPE(item)>
#define _pw_pbl_INTERFACE_TMP_PARM(item) typename _pw_pbl_INTERFACE_RESULT(item), typename... _pw_pbl_INTERFACE_PARMS(item)
#define _pw_pbl_INTERFACE_TMP_ARGU(item) _pw_pbl_INTERFACE_RESULT(item)(_pw_pbl_INTERFACE_PARMS(item)... _p)

/// 定义duck typing接口的便捷宏
/// @param name 接口名称
/// @param templargs 接口模板参数列表项，当定义模板时由于语法原因必须手工提供
/// @param __VA_ARGS__ 接口要求的方法名称和类型，如果是operator或重载须在第三个参数指定标识名字（接口内唯一），如(methodA, void(int)),(methodB, bool(int,int)),(operator(), char(bool), methodC),...
/// @sample PW_PBL_INTERFACE(IReadWrite, (read, char*(size_t)), (write, size_t(const char*, size_t)), (operator(), void(void), call));
/// @sample template<typename T> PW_PBL_INTERFACE_T(IReadWrite, <T>, (read, T*(size_t)), (write, size_t(const T*, size_t)));
/// @note 当对象类型并不直接支持接口时，可通过特化接口ClassVTable来实现将对象构造为接口对象，一般为template <> constexpr Iname::TRawVTable ClassVTable<T> = {...}
#define PW_PBL_INTERFACE_T(name, templargs, ...)                                                                     \
	class name : public ::pw_pbl::Interface::TBox<name templargs>                                                    \
	{                                                                                                                \
		using _tBox = ::pw_pbl::Interface::TBox<name>;                                                               \
		using _tBox::_tBox;                                                                                          \
                                                                                                                     \
		template <typename... _tFunc>                                                                                \
		struct _tRef;                                                                                                \
                                                                                                                     \
		template <PW_PBL_FOR_EACH(_pw_pbl_INTERFACE_TMP_PARM, (, ), __VA_ARGS__)>                                    \
		struct _tRef<PW_PBL_FOR_EACH(_pw_pbl_INTERFACE_TMP_ARGU, (, ), __VA_ARGS__)>                                 \
		{                                                                                                            \
			PW_PBL_FOR_EACH(_pw_pbl_INTERFACE_VMETHOD, (), __VA_ARGS__)                                              \
		};                                                                                                           \
                                                                                                                     \
	public:                                                                                                          \
		struct TRawVTable                                                                                            \
		{                                                                                                            \
			PW_PBL_FOR_EACH(_pw_pbl_INTERFACE_VTABLE_DEFI, (;), __VA_ARGS__);                                        \
		};                                                                                                           \
                                                                                                                     \
		using TRawRef = _tRef<PW_PBL_FOR_EACH(_pw_pbl_INTERFACE_TYPE, (, ), __VA_ARGS__)>;                           \
                                                                                                                     \
		template <typename _tObj>                                                                                    \
		static constexpr bool CanFrom = requires { PW_PBL_FOR_EACH(_pw_pbl_INTERFACE_REUQIRES, (;), __VA_ARGS__); }; \
                                                                                                                     \
		template <typename _tObj>                                                                                    \
		static constexpr TRawVTable ClassVTable{PW_PBL_FOR_EACH(_pw_pbl_INTERFACE_VTABLE_INIT, (, ), __VA_ARGS__)};  \
	}

/// 定义duck typing接口的便捷宏
/// @note 非模板接口的简化，其它说明与PW_PBL_INTERFACE_T相同
/// @see PW_PBL_INTERFACE_T
#define PW_PBL_INTERFACE(name, ...) PW_PBL_INTERFACE_T(name, , __VA_ARGS__)

namespace pw_pbl
{
	/// 任意对象接口
	/// @note 所有接口隐含IAny接口
	/// @note 一般只用于内部标记，除析构函数外不提供额外操作方法，显式使用时一般用于同步锁之类只依赖析构函数的对象
	class IAny : public Interface::TBox<IAny>
	{
	public:
		using TRawVTable = Interface::_imp::SVTable<>;
		template <typename _tObj>
		static constexpr bool CanFrom = true;
		template <typename _tObj>
		static const TRawVTable ClassVTable;
	};

	template <typename F>
	class IFunction;

	/// 函数对象接口，默认混合装箱
	/// @tparam R 函数对象的返回类型
	/// @tparam ...P 函数对象的参数类型
	template <typename R, typename... P>
	class IFunction<R(P...)> : public Interface::TBox<IFunction<R(P...)>, vtAllocLayout<{}>, Box<>>
	{
		using _tBox = Interface::TBox<IFunction, vtAllocLayout<{}>, Box<>>;
		using _tBox::_tBox;

	public:
		struct TRawVTable
		{
			Interface::TStaticVFunc<R(P...)> *_operatorCall;
		};

		struct TRawRef
		{
			inline R operator()(this const auto &self, P... p) { return self.VTable()._operatorCall(self.pObj(), std::forward<P>(p)...); }
		};

		template <typename _tObj>
		static constexpr bool CanFrom = requires { requires std::is_invocable_r_v<R, _tObj, P...>; };

		template <typename _tObj>
		static constexpr TRawVTable ClassVTable{[](void *ptr, P... p) -> R { return (*(_tObj *)ptr)(std::forward<P>(p)...); }};
	};

	/// 检查类型是否满足函数对象接口的concept
	/// @tparam T 要检查的类型
	/// @tparam F 形如Result(Parms...)的函数原型
	template <typename T, typename F>
	concept ccFunction = ccHasInterface<T, IFunction<F>>;

	/// 合并接口
	/// @tparam ...DSC 要合并的接口描述
	/// @note IAny为每个接口隐含的，不能添加合并
	template <Interface::ccNotIJoin... DSC>
	class IJoin<DSC...> : public Interface::TBox<IJoin<DSC...>>
	{
		using _tBox = Interface::TBox<IJoin<DSC...>>;
		using _tBox::_tBox;

	public:
		struct TRawVTable : public DSC::TRawVTable...
		{};

		struct TRawRef : public DSC::TRawRef...
		{};

		template <typename _tObj>
		static constexpr bool CanFrom = (DSC::template CanFrom<_tObj> && ...);

		template <typename _tObj>
		static constexpr TRawVTable ClassVTable{{DSC::template ClassVTable<_tObj>}...};

	public:
		template <Interface::ccNotIJoin... OTHER_DSC>
		using Append = IJoin<DSC..., OTHER_DSC...>;
		template <Interface::ccIsIJoin... OTHER>
		using Concat = typename Interface::Concat<IJoin, OTHER...>::type;
	};
} // namespace pw_pbl

#endif // PW_PBL_INTERFACE_HPP
